#include <stdio.h>
#include <math.h>

enum coordinate_type { RECTANGULAR, POLAR };
struct complex_struct {
	enum coordinate_type t;
	double a, b;
};
// get part of complex_struct
double real_part(struct complex_struct z)
{
    if(z.t == RECTANGULAR)
        return z.a;
    else
        return z.a * cos(z.b);
}

double img_part(struct complex_struct z)
{
    if(z.t == RECTANGULAR)
        return z.b;
    else
        return z.a * sin(z.b);
}

double magnitude(struct complex_struct z)
{
    if(z.t == RECTANGULAR)
        return sqrt(z.a * z.a + z.b * z.b);
    else
        return z.a;
}

double angle(struct complex_struct z)
{
    if(z.t == RECTANGULAR)
        return atan2(z.b, z.a);
    else
        return z.b;

}

// build complex_struct
struct complex_struct make_from_real_img(double x, double y)
{
	struct complex_struct z;
	z.t = RECTANGULAR;
	z.a = x;
	z.b = y;
	return z;
}

struct complex_struct make_from_mag_ang(double r, double A)
{
	struct complex_struct z;
	z.t = POLAR;
	z.a = r;
	z.b = A;
	return z;
}
// add/minus/mutiply/divide
struct complex_struct add_complex(struct complex_struct z1, struct complex_struct z2)
{
	return make_from_real_img(real_part(z1) + real_part(z2),
				  img_part(z1) + img_part(z2));
}

struct complex_struct sub_complex(struct complex_struct z1, struct complex_struct z2)
{
	return make_from_real_img(real_part(z1) - real_part(z2),
				  img_part(z1) - img_part(z2));
}

struct complex_struct mul_complex(struct complex_struct z1, struct complex_struct z2)
{
	return make_from_mag_ang(magnitude(z1) * magnitude(z2),
				 angle(z1) + angle(z2));
}

struct complex_struct div_complex(struct complex_struct z1, struct complex_struct z2)
{
	return make_from_mag_ang(magnitude(z1) / magnitude(z2),
				 angle(z1) - angle(z2));
}

// print
void print_complex(struct complex_struct z)
{
    double real,img;
    real = real_part(z);
    img = img_part(z);
    if(img == 0.0)
    {

        printf("z = %lf.\n", real);

    }
    else if(real == 0)
    {
        printf("z = %lfi.\n", img);
    }
    else
    {
        if(real <= 0.0)
            printf("z = %lf", real);
        else
            printf("z = %lf", real);
        if(img <= 0.0)
            printf("%lfi.\n", img);
        else
            printf("+%lfi.\n", img);
        return;
    }
}

int main(void)
{
//    double a1, b1, a2, b2;
    struct complex_struct z1, z2;
//    printf("Enter the complex you want to struct:");
//    scanf("%lf%lf", &a1, &b1);
//    printf("Enter the complex you want to struct:");
//    scanf("%lf%lf", &a2, &b2);
    z1 = make_from_mag_ang(5, 0.927295);
    z2 = make_from_real_img(2, 3);

    // test print
    print_complex(z1);
    print_complex(z2);

    // test  magnitude & angle
    printf("The magnitude of z1 is %lf, the angle is %lf.\n" ,magnitude(z1), angle(z1));
    printf("The magnitude of z2 is %lf, the angle is %lf.\n" ,magnitude(z2), angle(z2));

    // test +-x/
    print_complex(add_complex(z1, z2));
    print_complex(sub_complex(z1, z2));
    print_complex(mul_complex(z1, z2));
    print_complex(div_complex(z1, z2));

}
